package org.wak.gui.modern
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import gs.TweenLite;
	
	import org.wak.gui.events.GuiEvent;
	import org.wak.inventory.Inventory;
	import org.wak.inventory.InventoryItem;
	import org.wak.inventory.events.InventoryEvent;
	import org.wak.main.AdventureMaster;
	import org.wak.utils.IIterator;
	import org.wak.utils.WakSimpleButton;

	/**
	 * Class to render the player's inventory in the modern gui. 
	 * 
	 */	
	public class ModernInventoryDisplay extends Sprite
	{
		// rows of items to display
		protected var mRows:int = 0 ;
		// columns of items to display
		protected var mCols:int = 0 ;
		
		// width of each item in pixels
		protected var mItemWidth:int = 0 ;
		
		// height of each item in pixels
		protected var mItemHeight:int = 0 ;
		
		
		// pixels which separates the item columns
		protected var mColsSeparator:int = 1 ;
		
		// the inventory to render.
		protected var mInventory:Inventory = null ;
		
		// arrow up to scroll the inventory.
		protected var mArrowRight:WakSimpleButton = null ;
		
		// Arrow down to scroll the inventory.
		protected var mArrowLeft:WakSimpleButton = null ;
		
		protected var mItemsArray:Array = null ;
		
		// Asoc array from Sprite reference to InventoryItem.
		protected var mSpriteToItem:Array = null ;
		
		// starting x to draw the items.
		protected var mItemsX:Number = 0 ;
		// starting y to draw the items.
		protected var mItemsY:Number = 0 ;
		
		protected var mInventoryMask:Sprite = null ;
		
		// the mouse selected item by over or click.
		protected var mSelectedItem:Sprite = null;
		
		// layer where the items are added to easily handle the scroll.
		protected var mScrollingLayer:Sprite = null ;
		protected var mScrollingLayerIsMoving:Boolean = false ;
		protected var mScrollingLayerDest:Number = 0 ;
		
		protected var mTotalRows:int = 0;
		
		protected var mBackground:DisplayObject = null ;
		
		/**
		 * Constructor 
		 * @param pInventory the inventory of the player's character
		 * @param pCols visible columns that the inventory will have on screen.
		 * @param pItemWidth max width in pixels of an item on the inventory
		 * @param pItemHeight max height in pixels of an item on the inventory
		 * 
		 */		
		public function ModernInventoryDisplay(pInventory:Inventory, pCols:int = 4, pItemWidth:int = 70, pItemHeight:int = 44)
		{
			super();
			mInventory = pInventory ;
			mRows = 1 ;
			mCols = pCols ;
			mItemWidth = pItemWidth ;
			mItemHeight = pItemHeight ;
			mInventory = pInventory ;
			
			mScrollingLayer = new Sprite
			this.addChild(mScrollingLayer);
			
			mItemsArray = new Array();
			mSpriteToItem = new Array();
			
			addEventListener(Event.ADDED_TO_STAGE, OnAddedToStage );
		}
		
		/**
		 * Button to scroll right the inventory. 
		 * @param value
		 * 
		 */		
		public function set arrowRight(value:WakSimpleButton):void
		{
			mArrowRight = value ;
		}
		
		public function set background(value:DisplayObject):void
		{
			if( value == null )
				return ;
				
			mBackground = value ;
			this.addChild(mBackground);
			this.setChildIndex(mBackground,0);
		}
		
		/**
		 * Button to scroll left the inventory.
		 * @param value
		 * 
		 */		
		public function set arrowLeft(value:WakSimpleButton):void
		{
			mArrowLeft = value ;
		}
		
		public function set itemSeparatorSpace(value:Number):void
		{
			mColsSeparator = value ;
		} 
		
		public function set itemsY(value:Number):void
		{
			mItemsY = value ;
		} 
		
		protected function OnAddedToStage(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, OnAddedToStage );
			
			// Create the scrolling buttons
			if(mArrowLeft == null)
			{
				mArrowLeft = CreateDownArrow();
				mArrowLeft.x = mArrowLeft.width ;
				mArrowLeft.y = mArrowLeft.height / 2;
			}
			else
			{
				mArrowLeft.x = 0 ;
				mArrowLeft.y = mArrowLeft.height / 2;
			}
			
			addChild(mArrowLeft);
			
			mArrowLeft.addEventListener(MouseEvent.MOUSE_UP, OnScrollLeft );
				
			if(mArrowRight == null)
			{
				mArrowRight = CreateRightArrow();
				mArrowRight.x = mArrowLeft.width + mCols * (mItemWidth + mColsSeparator) - mArrowRight.width - mColsSeparator;
				mArrowRight.y = mArrowRight.height / 2; 
			}
			else
			{
				mArrowRight.x = (mCols * (mItemWidth + mColsSeparator)) + mColsSeparator + mArrowRight.width ;
				mArrowRight.y = mArrowRight.height / 2; 
			}
			addChild(mArrowRight);
			mArrowRight.addEventListener(MouseEvent.MOUSE_UP, OnScrollRight );
			
			mItemsX =  mArrowLeft.width  ;
			//mItemsY = 1 ;
			
			
			//trace("left:"+mArrowLeft.width + " r:"+ mArrowRight.width);
			// Set the scrolling mask
			mInventoryMask = new Sprite() ;
			mInventoryMask.graphics.beginFill(0xFFFFFF);
			mInventoryMask.graphics.drawRect(0,0, (mCols * (mItemWidth + mColsSeparator)) - mColsSeparator , mItemHeight + 1 );
			mInventoryMask.graphics.endFill() ;
			
			mInventoryMask.x = mArrowLeft.width ;
			mInventoryMask.y = 0 ;
			this.addChild(mInventoryMask);
			mScrollingLayer.mask = mInventoryMask ;
			
			// fill the inventory
			FillInventory( mInventory.GetItems() );
			
			// enable or disable scrolling buttons.
			if( (mItemsArray.length ) > mCols )
			{
				mArrowRight.enabled = true ;
			}
			else
			{
				mArrowRight.enabled = false ;
			}
			
			mArrowLeft.enabled = false ;
			
			mInventory.addEventListener(InventoryEvent.ITEM_ADDED, OnItemAdded );
			mInventory.addEventListener(InventoryEvent.ITEM_REMOVED,OnItemRemoved );
			
			
			this.addEventListener(Event.REMOVED_FROM_STAGE, OnRemovedToStage );
		}
		
		protected function OnRemovedToStage(event:Event):void
		{
			this.removeEventListener(Event.REMOVED_FROM_STAGE, OnRemovedToStage );
			
			for each( var item:Sprite in mItemsArray)
			{
				item.addEventListener(MouseEvent.MOUSE_OVER, OnItemMouseOver );
				item.addEventListener(MouseEvent.MOUSE_OUT, OnItemMouseOut );
				item.addEventListener(MouseEvent.CLICK, OnItemMouseClick );
			}
			
			mInventory.removeEventListener(InventoryEvent.ITEM_ADDED, OnItemAdded );
			mInventory.removeEventListener(InventoryEvent.ITEM_REMOVED,OnItemRemoved );
			this.addEventListener(Event.ADDED_TO_STAGE, OnAddedToStage );
		}
		
		protected function OnItemMouseOver(event:MouseEvent):void
		{
			if(mSelectedItem != event.target )
			{
				mSelectedItem = event.target as Sprite;
				var fItem:InventoryItem = mSpriteToItem[mSelectedItem.name] as InventoryItem;
				//trace("OnItemMouseOver "+ fItem.interactableId );
				var fEvent:GuiEvent = new GuiEvent( GuiEvent.INVENTORY_ITEM_OVER,"",fItem);
				this.dispatchEvent( fEvent );
			}
		}
		
		protected function OnItemMouseOut(event:MouseEvent):void
		{
			if( !mSelectedItem.hitTestPoint( event.stageX, event.stageY, true) )
			{
				var fTarget:Sprite = event.target as Sprite;
				var fItem:InventoryItem = mSpriteToItem[fTarget.name] as InventoryItem;
				var fEvent:GuiEvent = new GuiEvent( GuiEvent.INVENTORY_ITEM_OUT,"",fItem);
				this.dispatchEvent( fEvent );
				
				mSelectedItem = null ;
			}
		}
		
		protected function OnItemMouseClick(event:MouseEvent):void
		{
		
			mSelectedItem = event.target as Sprite;
			var fItem:InventoryItem = mSpriteToItem[mSelectedItem.name] as InventoryItem;
			var fEvent:GuiEvent = new GuiEvent( GuiEvent.INVENTORY_ITEM_SELECTED,"",fItem);
			this.dispatchEvent( fEvent );
		
		}
		
		
		
		protected function FillInventory( pItItems:IIterator ):void
		{
			var fNewItem:InventoryItem = null ;
			var fItemDisplay:Sprite = null ;
			
			var fCurrentX:Number = mItemsX ;
			var fCurrentY:Number = mItemsY ;
			
			var fRowCounter:int = 0 ;
			var fColCounter:int = 0 ;
			
			while(pItItems.hasNext())
			{
				fNewItem = pItItems.next() as InventoryItem ;
				fItemDisplay = fNewItem.itemDisplay ;
				//fItemDisplay.x = mItemsX + (fColCounter * mItemWidth) + mColsSeparator ;
				fCurrentX = (fColCounter * (mItemWidth + mColsSeparator)) ;
				fItemDisplay.x = mItemsX + fCurrentX ;
				fItemDisplay.y = mItemsY ;
				
				//trace("fItemDisplay.y: "+fItemDisplay.y);
				
				mScrollingLayer.addChild(fItemDisplay);
				mItemsArray.push( fItemDisplay );
				mSpriteToItem[fItemDisplay.name] = fNewItem ;
				fItemDisplay.addEventListener(MouseEvent.MOUSE_OVER, OnItemMouseOver );
				fItemDisplay.addEventListener(MouseEvent.MOUSE_OUT, OnItemMouseOut );
				fItemDisplay.addEventListener(MouseEvent.CLICK, OnItemMouseClick );
				
				fColCounter++ ;
				/* 
				if( fColCounter >= mCols )
				{
					fRowCounter++ ;
					fColCounter = 0 ;
				}
				 */
				
			}
			
			mTotalRows = mItemsArray.length / mCols ;
			
		}
		
		protected function OnItemAdded(event:InventoryEvent):void
		{
	
			var fNewItem:InventoryItem = event.inventoryItem ;
			
			mItemsArray.push( fNewItem.itemDisplay );
			mSpriteToItem[fNewItem.itemDisplay.name] = fNewItem ;
			
			RefreshItemsPositions( mItemsArray );
			
			var fNewItemCol:int = (mScrollingLayer.x + fNewItem.itemDisplay.x) / (mItemWidth + mColsSeparator) ;
			
			//trace("OnItemAdded:"+ fNewItemCol );
			
			fNewItem.itemDisplay.addEventListener(MouseEvent.MOUSE_OVER, OnItemMouseOver );
			fNewItem.itemDisplay.addEventListener(MouseEvent.MOUSE_OUT, OnItemMouseOut );
			fNewItem.itemDisplay.addEventListener(MouseEvent.CLICK, OnItemMouseClick );
			
			if( mItemsArray.length <= mCols )
			{
				return ;
			}
			
			var fColsDif:int = fNewItemCol - (mCols - 1);
			//trace("fColsDif:"+fColsDif);
			
			ScrollRightCols(fColsDif);
			
			
		}
		
		protected function GetItemDisplayInCol(pCol:int):DisplayObject
		{
			var fItemCol:int = 0 ;
			
			for each( var item:DisplayObject in mItemsArray)
			{
				fItemCol = mScrollingLayer.x + item.x / (mItemWidth ) ;
				if( fItemCol == pCol)
					return item ;
			}
			
			return null ;
		}
		
		protected function OnItemRemoved(event:InventoryEvent):void
		{
			var fRemovedItem:InventoryItem = event.inventoryItem ;
			var fIndex:int = mItemsArray.indexOf(fRemovedItem.itemDisplay);
			
			if(fIndex >= 0)
			{
				mItemsArray.splice(fIndex,1);
				mSpriteToItem[fRemovedItem.itemDisplay.name] = null ;
				if(mScrollingLayer.contains( fRemovedItem.itemDisplay ) )
					mScrollingLayer.removeChild( fRemovedItem.itemDisplay);
					
				fRemovedItem.itemDisplay.removeEventListener(MouseEvent.MOUSE_OVER, OnItemMouseOver );
				fRemovedItem.itemDisplay.removeEventListener(MouseEvent.MOUSE_OUT, OnItemMouseOut );
				fRemovedItem.itemDisplay.removeEventListener(MouseEvent.CLICK, OnItemMouseClick );
				
				RefreshItemsPositions( mItemsArray );
			}
		}
		
		protected function RefreshItemsPositions(pItemsArray:Array):void
		{
			var fRowCounter:int = 0 ;
			var fColCounter:int = 0 ;
			
			var fFirstItem:Sprite = mItemsArray[0] as Sprite ;
			
			for each( var item:Sprite in pItemsArray)
			{
				item.x = mItemsX + (fColCounter * (mItemWidth + mColsSeparator)) ; 
				item.y = mItemsY  ;
				
				if( !mScrollingLayer.contains(item) )
					mScrollingLayer.addChild(item);
					
				fColCounter++ ;
				/* 
				if( fColCounter >= mCols )
				{
					fRowCounter++ ;
					fColCounter = 0 ;
				}
				 */
			}				
		}
		
		
		
		protected function CreateRightArrow():WakSimpleButton
		{
			var fBtn:WakSimpleButton = null 
			 
			var fUp:Sprite = DrawLeftArrow(0x120012,0xFFFFFF);
			fUp.rotation = -90 ;
			fUp.x = fUp.width + 1; 
			fUp.y = fUp.height ;
			
			var fOver:Sprite = DrawLeftArrow(0x120012,0xFFFFFF);
			fOver.rotation = fUp.rotation ;
			fOver.x = fUp.width + 1; 
			fOver.y = fUp.height ;
			
			var fDown:Sprite = DrawLeftArrow(0x120012,0xFFFFFF);
			fDown.rotation = fUp.rotation ;
			fDown.x = fUp.width + 1; 
			fDown.y = fUp.height ;
			
			fBtn = new WakSimpleButton( fUp, fOver, fDown);
			fBtn.y = 2 ;
			fBtn.enabled = false ;
			
			return fBtn ;
		}
		
		protected function CreateDownArrow():WakSimpleButton
		{
			var fUp:Sprite = DrawLeftArrow(0x120012,0xFFFFFF);
			var fOver:Sprite = DrawLeftArrow(0x120012,0xFFFFFF);
			var fDown:Sprite = DrawLeftArrow(0x120012,0xFFFFFF);
			var fBtn:WakSimpleButton = new WakSimpleButton(fUp,fOver,fDown);
			
			fBtn.y = fBtn.height + 2 ;
			fBtn.enabled = false ;
			return fBtn;
			  
		}
		
		protected function DrawLeftArrow(pBgColor:uint, pArrowColor:uint):Sprite
		{
			var fArrow:Sprite = new Sprite();
			fArrow.graphics.beginFill(pBgColor,1);
			fArrow.graphics.drawRect(0,0,26,20);
			fArrow.graphics.endFill();
			
			fArrow.graphics.lineStyle(2,pArrowColor);
			fArrow.graphics.moveTo(9,2);
			fArrow.graphics.lineTo(9,5);
			
			fArrow.graphics.moveTo(9,5);
			fArrow.graphics.lineTo(1,5);
			
			fArrow.graphics.moveTo(1,5);
			fArrow.graphics.lineTo(13,20);
			
			fArrow.graphics.moveTo(13,20);
			fArrow.graphics.lineTo(26,5);
			
			fArrow.graphics.moveTo(26,5);
			fArrow.graphics.lineTo(18,5);
			
			fArrow.graphics.moveTo(18,5);
			fArrow.graphics.lineTo(18,2);
			
			fArrow.graphics.moveTo(18,2);
			fArrow.graphics.lineTo(9,2);
			fArrow.graphics.endFill();
			
			fArrow.rotation = 90 ;
			
			
			return fArrow ;
			
		}
		
		protected function OnScrollLeft(event:Event):void
		{
			if( !(mArrowLeft.enabled) )
			{
				// for testing only.//////
				//var fItem:InventoryItem = AdventureMaster.InventoryItemsMngr.GetInventoryItem("ISword2");
				//mInventory.AddItem(fItem);
				//////////////////////////
				
				return ;
			}
			
			ScrollLeft();
		}
		
		protected function OnScrollRight(event:Event):void
		{
			if( !(mArrowRight.enabled) )
			{
				return ;
			}
			
			ScrollRight();
		}
		
		
		
		protected function UpdateScrollButtons(pDirection:Number):void
		{
			
			
			//pDirection = -1 * pDirection ;
			var fLastItem:DisplayObject = mItemsArray[mItemsArray.length -1] ;
			
			var fLastItemRealX:Number = (mScrollingLayer.x + fLastItem.x ) + ( (mItemWidth + mColsSeparator) * pDirection) ; 
			
			var fLastItemRow:int = fLastItemRealX / (mItemWidth + mColsSeparator) ;
			//trace("fLastItemRow:"+fLastItemRow);
			if( fLastItemRow >= mCols )
			{
				mArrowRight.enabled = true ;
			}
			else
			{
				mArrowRight.enabled = false ;
			}
			
			var fFirstItem:DisplayObject = mItemsArray[0] ;
			var fFirstItemRealX:Number = (fFirstItem.x + mScrollingLayer.x) + ( (mItemWidth + mColsSeparator) * pDirection) ;
			
			if( fFirstItemRealX < 0 )
			{
				mArrowLeft.enabled = true ;
			}
			else if(fFirstItemRealX >= 0 )
			{
				mArrowLeft.enabled = false ;
			}
			
			//mArrowRight.enabled = true ;
			//mArrowLeft.enabled = true ;
			
		}
		
		private var mScrollTweenSpeed:Number = 0.5
		
		protected function ScrollLeft():void
		{
			if(!mScrollingLayerIsMoving)
			{
				mScrollingLayerDest = mScrollingLayer.x + mItemWidth + mColsSeparator ;
				//mScrollingLayer.x += mItemWidth + mColsSeparator ;
				TweenLite.to(mScrollingLayer,mScrollTweenSpeed,{x: mScrollingLayerDest, onComplete:OnScrollCompleted});
				mScrollingLayerIsMoving = true ;
				UpdateScrollButtons(+1);
			}
			/*
			else
			{
				mScrollingLayerDest = (mScrollingLayerDest - mScrollingLayer.x) + mScrollingLayer.x + mItemWidth + mColsSeparator
			}
			*/
		}
		
		protected function ScrollRight():void
		{
			if(!mScrollingLayerIsMoving)
			{
				mScrollingLayerDest = mScrollingLayer.x - (mItemWidth + mColsSeparator) ;
				//mScrollingLayer.x -= mItemWidth + mColsSeparator ;
				TweenLite.to(mScrollingLayer,mScrollTweenSpeed,{x:mScrollingLayerDest, onComplete:OnScrollCompleted});
				mScrollingLayerIsMoving = true ;
				UpdateScrollButtons(-1);
				
			}
			/*
			else
			{
				mScrollingLayerDest = (mScrollingLayerDest - mScrollingLayer.x) + mScrollingLayer.x - mItemWidth + mColsSeparator
			}
			*/
		}
		
		protected function ScrollRightCols(pNum:int):void
		{
			if(!mScrollingLayerIsMoving)
			{
				mScrollingLayerDest = mScrollingLayer.x - ((mItemWidth + mColsSeparator) * pNum);
				//mScrollingLayer.x -= mItemWidth + mColsSeparator ;
			}
			else
			{
				mScrollingLayerDest = (mScrollingLayerDest - mScrollingLayer.x) + mScrollingLayer.x - ((mItemWidth + mColsSeparator) * pNum)
			}
			TweenLite.to(mScrollingLayer,mScrollTweenSpeed,{x:mScrollingLayerDest, onComplete:OnScrollCompleted});
			mScrollingLayerIsMoving = true ;
			UpdateScrollButtons(-pNum);
			
		}
		
		protected function OnScrollCompleted():void
		{
			mScrollingLayerIsMoving = false ;
		}
		
		
		
	}
}